---
title: Regulated Coin and Deny List
description: You can create regulated coins on Sui, such as stablecoins. These coins are similar to other coins like SUI, but include the ability to control access to the coin using a deny list.
---

The Sui [Coin](../../../standards/coin.mdx) standard provides a `create_regulated_currency` function to create coins. This function is different than `create_currency` in that it generates a coin that you can block certain addresses from being able to use those coins in transactions. This ability is a requirement for assets like stablecoins.

Behind the scenes, `create_regulated_currency` uses the `create_currency` function to create the coin, but also produces a `DenyCap` object that allows its bearer to control access to the coin's deny list in a `DenyList` object. Consequently, the way to create a coin using `create_regulated_currency` is similar to the previous example, with the addition of a transfer of the `DenyCap` object to the module publisher.

{@inject: examples/move/coin/sources/regcoin.move#regulate}

When you deploy the previous module using `sui client publish`, the console responds with transaction effects, including the creation of the following objects:

```sh
...

Object Changes

Created Objects:

   ObjectID: <OBJECT-ID>
   Sender: <SENDER-ADDR>
   Owner: Immutable
   ObjectType: 0x2::coin::CoinMetadata<<PACKAGE-ID>::regcoin::REGCOIN>
   Version: <VERSION-NUMBER>
   Digest: <DIGEST-HASH>

   ObjectID: <OBJECT-ID>
   Sender: <SENDER-ADDR>
   Owner: Account Address ( <PUBLISHER-ADDRESS )
   ObjectType: 0x2::package::UpgradeCap
   Version: <VERSION-NUMBER>
   Digest: <DIGEST-HASH>

   ObjectID: <OBJECT-ID>
   Sender: <SENDER-ADDR>
   Owner: Immutable
   ObjectType: 0x2::coin::RegulatedCoinMetadata<<PACKAGE-ID>::regcoin::REGCOIN>
   Version: <VERSION-NUMBER>
   Digest: <DIGEST-HASH>

   ObjectID: <OBJECT-ID>
   Sender: <SENDER-ADDR>
   Owner: Account Address ( <PUBLISHER-ADDRESS )
   ObjectType: 0x2::coin::DenyCap<<PACKAGE-ID>::regcoin::REGCOIN>
   Version: <VERSION-NUMBER>
   Digest: <DIGEST-HASH>


   ObjectID: <OBJECT-ID>
   Sender: <SENDER-ADDR>
   Owner: Account Address ( <PUBLISHER-ADDRESS )
   ObjectType: 0x2::coin::TreasuryCap<PACKAGE-ID>::regcoin::REGCOIN>
   Version: <VERSION-NUMBER>
   Digest: <DIGEST-HASH>

...
```

As you might have noticed, the publish action creates a `RegulatedCoinMetadata` object along with the standard `CoinMetadata` object. You don't need to explicitly call the `freeze_object` on the `RegulatedCoinMetadata` object, however, because `create_regulated_currency` automatically performs this action.

The output also shows the three objects that the publisher now owns: `UpgradeCap` for [package upgrades](../../../concepts/sui-move-concepts/packages/upgrade.mdx), `TreasuryCap` for minting or burning coins, and the `DenyCap` for adding or removing addresses to or from the deny list for this coin.

## DenyList

The Sui framework provides a `DenyList` singleton, shared object that the bearer of a `DenyCap` can access to specify a list of addresses that are unable to use a Sui core type. The initial use case for `DenyList`, however, focuses on limiting access to coins of a specified type. This is useful, for example, when creating a regulated coin on Sui that requires the ability to block certain addresses from using it as inputs to transactions. Regulated coins on Sui satisfy any regulations that require the ability to prevent known bad actors from having access to those coins. 

:::info

The `DenyList` object is a system object that has the address `0x403`. You cannot create it yourself.

:::


### Manipulate deny list

For the ability to manipulate the addresses assigned to the deny list for your coin, you must add a few functions to the previous example.

{@inject: examples/move/coin/sources/regcoin.move#fun=add_addr_from_deny_list,remove_addr_from_deny_list noComments}

To use these functions, you pass the `DenyList` object (`0x403`), your `DenyCap` object ID, and the address you want to either add or remove. Using the Sui CLI, you could use `sui client call` with the required information:

{@include: ../../../snippets/info-gas-budget.mdx}

```shell
sui client call --function add_addr_from_deny_list --module regcoin --package <PACKAGE-ID> --args <DENY-LIST> <DENY-CAP> <ADDRESS-TO-DENY> --gas-budget <GAS-AMOUNT>
Transaction Digest: <DIGEST-HASH>
```

The console displays the response from the network, where you can verify the `DenyList` object is mutated.

```shell
...

MutatedObjects:

  ObjectID: 0x0...403               
  Sender: <SENDER-ADDRESS>
  Owner: Shared
  ObjectType: 0x2::deny_list::DenyList
  Version: <VERSION-NUMBER>
  Digest: <DIGEST-HASH>

...

```

For all `Coin` functions available, see the Sui framework [`coin` module documentation](https://github.com/MystenLabs/sui/blob/main/crates/sui-framework/docs/sui-framework/coin.md).

## Related links

- [Closed Loop Token standard](../../../standards/closed-loop-token.mdx): Details for the standard used to create tokens on Sui.
- [Source code](https://github.com/MystenLabs/sui/blob/main/examples/move/coin/sources/regcoin.move): The source code in GitHub for this example.
- [In-Game Tokens](./in-game-token.mdx): Example of how to create tokens for use as in-game currency.
- [Regulated Coin and Deny List](./loyalty.mdx): Example of how to create tokens that reward brand or service loyalty on the Sui network.